package com.xbongbong.saas.service.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.thread.LogThreadPoolBeanConfig;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.crm.strategy.TeamDynamicStrategy;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailAddTeamGroupDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailChangeMainDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailCoAddDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailCoDelDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailDisbandTeamDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailEditLabelDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailMainAddDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailMainDelDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailRenameDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailUpdateDTO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailAddTeamGroupVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailChangeMainVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailCoAddVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailCoDelVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailDisbandTeamVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditCoPerVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditLabelVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailMainAddVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailMainDelVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailRenameVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailVO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicEditTeamDTO;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.listbatch.pojo.TeamBatchPojo;
import com.xbongbong.pro.listbatch.pojo.dto.ChangeMainDTO;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.service.toolbox.statistic.help.TeamHelp;
import com.xbongbong.pro.team.TeamVerifyDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.ClueUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.UserTeamOperateTagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.ClueUserModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.TeamDetailService;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author: 汪腾伟
 * @date: Created in 2021/12/23 18:37
 * @description： 针对详情页的团队的Service层实现方法
 */
@Service
public class TeamDetailServiceImpl implements TeamDetailService {

    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private LogThreadPoolBeanConfig logThreadPoolBeanConfig;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private ClueModel clueModel;
    @Resource
    private ClueUserModel clueUserModel;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private TeamHelp teamHelp;


    private static final Logger LOG = LoggerFactory.getLogger(TeamDetailServiceImpl.class);

    /**
     * 详情页的团队信息，之所以返回是一个Object，是因为目前返回需要分隔离和共享。
     * 隔离和共享需要返回的东西有差，下面有两个用来接收返回的实体，所以统一用Object返回
     *
     * @param teamDetailDTO
     * @return
     */
    @Override
    public TeamDetailVO teamDetail(TeamDetailDTO teamDetailDTO) throws XbbException {
        return teamDataHelp.detail(teamDetailDTO);
    }

    /**
     * 编辑协同人权限
     *
     * @param teamDetailUpdateDTO 团队详情更新操作相关的接收实体
     * @return
     * @throws XbbException
     */
    @Override
    public TeamDetailEditCoPerVO editCoPermission(TeamDetailUpdateDTO teamDetailUpdateDTO) throws XbbException {
        TeamDetailEditCoPerVO teamDetailEditCoPerVO = teamDataHelp.editCoPermission(teamDetailUpdateDTO);
        return teamDetailEditCoPerVO;
    }


    /**
     * 解散团队
     * 思路:为啥不写在策略类里面，是因为解散团队操作只存在隔离模式下客户、线索
     * (1)团队解散后所有人员全部移除
     * (2)必须保留一个负责团队，最后一个团队无法解散，提示“团队解散失败，失败原因：必须保留一个团队
     *
     * @param teamDetailDisbandTeamDTO
     * @return
     */
    @Override
    public TeamDetailDisbandTeamVO disbandTeam(TeamDetailDisbandTeamDTO teamDetailDisbandTeamDTO) throws XbbException{
        Long dataId = teamDetailDisbandTeamDTO.getDataId();
        String corpid = teamDetailDisbandTeamDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailDisbandTeamDTO.getSaasMark(), teamDetailDisbandTeamDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }
        TeamDetailDisbandTeamVO teamDetailDisbandTeamVO = new TeamDetailDisbandTeamVO();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailDisbandTeamDTO, teamVerifyDTO);
        teamVerifyDTO.setTeamUserId(teamDetailDisbandTeamDTO.getMainUserId());
        Set<String> newDelMainUserList = new HashSet<>();
        newDelMainUserList.add(teamDetailDisbandTeamDTO.getMainUserId());
        teamVerifyDTO.setNewDelMainUserList(newDelMainUserList);
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(Collections.singletonList(teamDetailDisbandTeamDTO.getDataId()));
        teamVerifyDTO.setOperateTag(UserTeamOperateTagEnum.DEL_TEAM_TAG.getOperateTag());
        teamVerifyDTO.setLoginUser(teamDetailDisbandTeamDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailDisbandTeamVO;
    }

    /**
     *
     * 修改团队名称
     * 思路：目前编辑团队名称，只存在隔离模式下的客户和线索业务
     *
     * @param teamDetailRenameDTO 修改团队名称入参实体
     * @return
     */
    @Override
    public TeamDetailRenameVO renameTeam(TeamDetailRenameDTO teamDetailRenameDTO) throws XbbException{
        TeamDetailRenameVO teamDetailRenameVO = new TeamDetailRenameVO();
        Long id = teamDetailRenameDTO.getId();
        Long dataId = teamDetailRenameDTO.getDataId();
        String name = teamDetailRenameDTO.getName();
        Integer businessType = teamDetailRenameDTO.getBusinessType();
        String corpid = teamDetailRenameDTO.getCorpid();
        Long formId = teamDetailRenameDTO.getFormId();
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            CustomerUserEntity customerUserEntity = customerUserModel.getByKey(id, corpid);
            String beforeName = customerUserEntity.getName();
            Long beforeUpdateTime = customerUserEntity.getUpdateTime();
            if (!Objects.equals(name, customerUserEntity.getName())) {
                customerUserEntity.setName(name);
                customerUserModel.renameTeam(customerUserEntity);
                //更新主表更新时间
                customerModel.updateTime(dataId,corpid);
                //日志消息记录
                Runnable runnable = () -> {
                    try {
                        CustomerEntityExt customerEntityExt = customerModel.getByKey(customerUserEntity.getDataId(), corpid);
                        //获取用户信息
                        UserEntity userEntity = userModel.getByKey(customerUserEntity.getUserId(), corpid);
                        //获取表单信息
                        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                        OperateModuleTypeEnum operateModuleTypeEnum = OperateModuleTypeEnum.RESPONSIBLE_TEAM;
                        OperateTypeEnum operateTypeEnum = OperateTypeEnum.EDIT;
                        UserVO loginUser = teamDetailRenameDTO.getLoginUser();
                        String userName = loginUser.getName();
                        String userId = loginUser.getUserId();
                        String customerName = customerEntityExt.getData().getString(CustomerManagementEnum.NAME.getAttr());
                        String opObjectName = userEntity.getName();
                        String contentObjectName = userEntity.getName() + I18nMessageUtil.getMessage(TeamMembersConstant.TEAM_SUFFIX);
                        String initBeforeName = "";
                        if(StringUtil.isEmpty(beforeName)){
                            initBeforeName =contentObjectName;
                        }else{
                            initBeforeName = beforeName;
                        }
                        String formName = paasFormEntityExt.getName();
                        String message = I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_CHANGE_TEAM);
                        String memo = String.format(message, userName, formName, customerName, opObjectName);
                        List<DetailLogPojo> detailArr = new ArrayList<>();
                        DetailLogPojo detailLogPojo = new DetailLogPojo(I18nMessageUtil.getMessage(TeamMembersConstant.TEAM_NAME),
                                initBeforeName, name);
                        detailArr.add(detailLogPojo);
                        userTeamHelp.getStringTime(beforeUpdateTime, DateTimeUtil.getInt(), detailArr);
                        mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, operateModuleTypeEnum, operateTypeEnum,
                                dataId.toString(), contentObjectName, memo, teamDetailRenameDTO.getHttpHeader());

                        // 动态
                        TeamDynamicStrategy teamDynamicStrategy = dynamicStrategyFactory.getTeamDynamicStrategyByBusinessType(businessType);
                        teamDynamicStrategy.editTeamName(DynamicEditTeamDTO.initDynamicEditTeamDTO(teamDetailRenameDTO,customerEntityExt,userEntity));
                    } catch (Exception e) {
                        LOG.error("com.xbongbong.saas.service.impl.TeamDetailServiceImpl.renameTeam fail", e);
                    }
                };
                logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);
            }
        }else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            ClueUserEntity clueUserEntity = clueUserModel.getByKey(id, corpid);
            String beforeName = clueUserEntity.getName();
            Long beforeUpdateTime = clueUserEntity.getUpdateTime();
            if (!Objects.equals(name, clueUserEntity.getName())) {
                clueUserEntity.setName(name);
                clueUserModel.renameTeam(clueUserEntity);
                //更新主表更新时间
                clueModel.updateTime(dataId,corpid);
                //日志消息记录
                Runnable runnable = () -> {
                    try {
                        ClueEntityExt clueEntityExt = clueModel.getByKey(clueUserEntity.getDataId(), corpid);
                        //获取用户信息
                        UserEntity userEntity = userModel.getByKey(clueUserEntity.getUserId(), corpid);
                        //获取表单信息
                        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                        OperateModuleTypeEnum operateModuleTypeEnum = OperateModuleTypeEnum.RESPONSIBLE_TEAM;
                        OperateTypeEnum operateTypeEnum = OperateTypeEnum.EDIT;
                        UserVO loginUser = teamDetailRenameDTO.getLoginUser();
                        String userName = loginUser.getName();
                        String userId = loginUser.getUserId();
                        String customerName = clueEntityExt.getSerialNo();
                        String opObjectName = userEntity.getName();
                        String contentObjectName = userEntity.getName() + I18nMessageUtil.getMessage(TeamMembersConstant.TEAM_SUFFIX);
                        String formName = paasFormEntityExt.getName();
                        String message = I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_CHANGE_TEAM);
                        String memo = String.format(message, userName, formName, customerName, opObjectName);
                        List<DetailLogPojo> detailArr = new ArrayList<>();
                        DetailLogPojo detailLogPojo = new DetailLogPojo(I18nMessageUtil.getMessage(TeamMembersConstant.TEAM_NAME),
                                beforeName, name);
                        detailArr.add(detailLogPojo);
                        userTeamHelp.getStringTime(beforeUpdateTime, DateTimeUtil.getInt(), detailArr);
                        mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, operateModuleTypeEnum, operateTypeEnum,
                                dataId.toString(), contentObjectName, memo, teamDetailRenameDTO.getHttpHeader());
                    } catch (Exception e) {
                        LOG.error("com.xbongbong.saas.service.impl.TeamDetailServiceImpl.renameTeam fail", e);
                    }
                };
                logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);
            }
        }


        return teamDetailRenameVO;
    }

    /**
     * 编辑团队里面的成员标签
     * 思路：每个团队都有编辑标签的功能，所以这个方法底层需要调用策略类里面的方法
     *
     * @param teamDetailEditLabelDTO 编辑团队成员标签的接收实体
     * @return
     */
    @Override
    public TeamDetailEditLabelVO editLabel(TeamDetailEditLabelDTO teamDetailEditLabelDTO) throws XbbException{
        TeamDetailEditLabelVO teamDetailEditLabelVO = teamDataHelp.editLabel(teamDetailEditLabelDTO);
        return teamDetailEditLabelVO;
    }

    /**
     * 团队详情新增团队
     *
     * @param teamDetailAddTeamGroupDTO 团队详情新增团队接收实体
     * @return
     */
    @Override
    public TeamDetailAddTeamGroupVO addTeamGroup(TeamDetailAddTeamGroupDTO teamDetailAddTeamGroupDTO) throws XbbException{
        Long dataId = teamDetailAddTeamGroupDTO.getDataId();
        String corpid = teamDetailAddTeamGroupDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailAddTeamGroupDTO.getSaasMark(), teamDetailAddTeamGroupDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }

        List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailAddTeamGroupDTO.getFormId(), teamDetailAddTeamGroupDTO.getSaasMark(), teamDetailAddTeamGroupDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_TEAM_TAG);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailAddTeamGroupVO teamDetailAddTeamGroupVO = new TeamDetailAddTeamGroupVO();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailAddTeamGroupDTO, teamVerifyDTO);
        Set<String> mainUserIdList = new HashSet<>();
        mainUserIdList.add(teamDetailAddTeamGroupDTO.getMainUserId());
        teamVerifyDTO.setDataId(Collections.singletonList(dataId));
        teamVerifyDTO.setNewAddMainUserList(mainUserIdList);
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setOperateTag(UserTeamOperateTagEnum.ADD_TEAM_TAG.getOperateTag());
        teamVerifyDTO.setLoginUser(teamDetailAddTeamGroupDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailAddTeamGroupVO;
    }

    /**
     * 负责人新增（目前只存在共享模式下）
     *
     * @param teamDetailMainAddDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamDetailMainAddVO mainAdd(TeamDetailMainAddDTO teamDetailMainAddDTO) throws XbbException {
        Long dataId = teamDetailMainAddDTO.getDataId();
        String corpid = teamDetailMainAddDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailMainAddDTO.getSaasMark(), teamDetailMainAddDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }

        List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailMainAddDTO.getFormId(), teamDetailMainAddDTO.getSaasMark(), teamDetailMainAddDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_MAIN);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailMainAddVO teamDetailMainAddVO = new TeamDetailMainAddVO();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailMainAddDTO, teamVerifyDTO);
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(new ArrayList<>(Arrays.asList(dataId)));
        teamVerifyDTO.setNewAddMainUserList(new HashSet<>(teamDetailMainAddDTO.getOwnerUserIds()));
        teamVerifyDTO.setLoginUser(teamDetailMainAddDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailMainAddVO;
    }

    /**
     * 替换负责人
     *
     * @param teamDetailChangeMainDTO
     * @return
     */
    @Override
    public TeamDetailChangeMainVO changeMain(TeamDetailChangeMainDTO teamDetailChangeMainDTO) throws XbbException {
        Long dataId = teamDetailChangeMainDTO.getDataId();
        String corpid = teamDetailChangeMainDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailChangeMainDTO.getSaasMark(), teamDetailChangeMainDTO.getBusinessType());

       List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailChangeMainDTO.getFormId(), teamDetailChangeMainDTO.getSaasMark(), teamDetailChangeMainDTO.getBusinessType(), UserTeamOperateTagEnum.UPDATE_MAIN);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailChangeMainVO teamDetailChangeMainVO = new TeamDetailChangeMainVO();
        ChangeMainDTO changeMainDTO = new ChangeMainDTO();
        BeanUtil.copyProperties(teamDetailChangeMainDTO, changeMainDTO);
        changeMainDTO.setDataIdList(new ArrayList<>(Arrays.asList(teamDetailChangeMainDTO.getDataId())));
        changeMainDTO.setBatchTag(BasicConstant.ZERO);
        try{
            listBatchService.changeMain(changeMainDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailChangeMainVO;
    }

    /**
     * 删除负责人（共享模式）
     *
     * @param teamDetailMainDelDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamDetailMainDelVO mainDel(TeamDetailMainDelDTO teamDetailMainDelDTO) throws XbbException {
        Long dataId = teamDetailMainDelDTO.getDataId();
        String corpid = teamDetailMainDelDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailMainDelDTO.getSaasMark(), teamDetailMainDelDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }

        List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailMainDelDTO.getFormId(), teamDetailMainDelDTO.getSaasMark(), teamDetailMainDelDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_MAIN);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailMainDelVO teamDetailMainDelVO = new TeamDetailMainDelVO();
        String mainUserId = teamDetailMainDelDTO.getMainUserId();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailMainDelDTO, teamVerifyDTO);
        teamVerifyDTO.setNewDelMainUserList(new HashSet<>(Collections.singletonList(mainUserId)));
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(Collections.singletonList(teamDetailMainDelDTO.getDataId()));
        teamVerifyDTO.setLoginUser(teamDetailMainDelDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailMainDelVO;
    }

    /**
     * 删除协同人
     *
     * @param teamDetailCoDelDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamDetailCoDelVO coDel(TeamDetailCoDelDTO teamDetailCoDelDTO) throws XbbException {
        Long dataId = teamDetailCoDelDTO.getDataId();
        String corpid = teamDetailCoDelDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailCoDelDTO.getSaasMark(), teamDetailCoDelDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }

        List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailCoDelDTO.getFormId(), teamDetailCoDelDTO.getSaasMark(), teamDetailCoDelDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_COUSER);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailCoDelVO teamDetailCoDelVO = new TeamDetailCoDelVO();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailCoDelDTO, teamVerifyDTO);
        teamVerifyDTO.setNewDelCoUserList(new HashSet<>(Collections.singletonList(teamDetailCoDelDTO.getCoUserId())));
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(Collections.singletonList(teamDetailCoDelDTO.getDataId()));
        teamVerifyDTO.setLoginUser(teamDetailCoDelDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailCoDelVO;
    }

    /**
     * 协同人新增
     *
     * @param teamDetailCoAddDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamDetailCoAddVO coAdd(TeamDetailCoAddDTO teamDetailCoAddDTO) throws XbbException {
        Long dataId = teamDetailCoAddDTO.getDataId();
        String corpid = teamDetailCoAddDTO.getCorpid();
        // 数据加锁
        String redisPrefix = teamDataHelp.getRedisPrefix(teamDetailCoAddDTO.getSaasMark(), teamDetailCoAddDTO.getBusinessType());
        boolean useAble = dataLocking(dataId, corpid, redisPrefix);
        if(!useAble){
            //已有他人使用
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100106);
        }

        List<TeamBatchPojo> teamBatchPojos = teamHelp.checkDataIsApproval(new ArrayList<>(Arrays.asList(dataId)), corpid, teamDetailCoAddDTO.getFormId(), teamDetailCoAddDTO.getSaasMark(), teamDetailCoAddDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_COUSER);
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            TeamBatchPojo teamBatchPojo = teamBatchPojos.get(0);
            throw new XbbException(teamBatchPojo.getCode(), teamBatchPojo.getFailMsgReason());
        }

        TeamDetailCoAddVO teamDetailCoAddVO = new TeamDetailCoAddVO();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(teamDetailCoAddDTO, teamVerifyDTO);
        teamVerifyDTO.setNewAddCoUserList(new HashSet<>(teamDetailCoAddDTO.getCoUserIds()));
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(Collections.singletonList(teamDetailCoAddDTO.getDataId()));
        teamVerifyDTO.setLoginUser(teamDetailCoAddDTO.getLoginUser());
        try{
            teamDataHelp.save(teamVerifyDTO);
        }catch (XbbException e){
            //数据解锁
            removeDataLock(dataId, corpid, redisPrefix);
            throw e;
        }
        //数据解锁
        removeDataLock(dataId, corpid, redisPrefix);
        return teamDetailCoAddVO;
    }


    /**
     * 数据加锁
     * @param dataId
     * @param corpid
     * @return false：数据已被加锁。true:数据可以使用
     */
    private boolean dataLocking(Long dataId, String corpid, String redisPrefix) {
        if (StringUtil.isEmpty(redisPrefix)) {
            return false;
        }
        String key = corpid + "_" + dataId;
        Long value = paasRedisHelper.getIncrNum(redisPrefix,key,10,1,1);
        if (value > 1L){
            return false;
        }
        return true;
    }

    /**
     * 数据去锁
     * @param dataId
     * @param corpid
     * @param redisPrefix
     * 创建时间 2020/12/8 7:15 PM
     * 修改时间 2020/12/8 7:15 PM
     * @author chy
     */
    private void removeDataLock(Long dataId, String corpid, String redisPrefix) {
        if (StringUtil.isEmpty(redisPrefix)) {
            return;
        }
        String key = corpid + "_" + dataId;
        paasRedisHelper.removeValue(redisPrefix,key);
    }



}
